#include "kpextMemoryResource.h"

using namespace kpext;


void BaseBuffer::rebuild(std::shared_ptr<RawBuffer> buf,
                         std::shared_ptr<RawDeviceMemory> mem,
                         size_t size)
{
    if(!buf || !mem){
        SPDLOG_ERROR("Rebuild kpext::xxxBuffer with null pointer!");
        return;
    }
    if(size < 1) size = 1;
    m_bufobj = buf;
    m_memory = mem;
    resize(size);
}

void BaseBuffer::rebuild(std::shared_ptr<RawBuffer> buf,
                         std::shared_ptr<RawDeviceMemory> mem,
                         size_t size, vk::BufferUsageFlags usage,
                         vk::MemoryPropertyFlags memprop)
{
    m_usage = usage;
    m_memProp = memprop;
    rebuild(buf, mem, size);
}

void BaseBuffer::resize(size_t size)
{
    if(!m_bufobj || !m_memory){
        SPDLOG_ERROR("Can not resize kpext::xxxBuffer with null pointer!");
        return;
    }
    if(size < 1){
        SPDLOG_ERROR("Can not resize kpext::xxxBuffer to zero bytes!");
        return;
    }

    m_memory->unmapFromHostMemory();

    bool res1 =
            m_bufobj->recreate(size,
                               m_usage
                               );

    if(!res1){
        SPDLOG_ERROR(__FUNCTION__  " Can not recreate kpext::RawBuffer!");
    }else{
        SPDLOG_DEBUG("Recreate kpext::RawBuffer");
    }

    bool res2 =
            m_memory->recreate(m_bufobj->getMemRequirements(),
                               m_memProp
                               );
    if(!res2){
        SPDLOG_ERROR(__FUNCTION__  " Can not recreate kpext::RawDeviceMemory!");
    }else{
        SPDLOG_DEBUG("Recreate kpext::RawDeviceMemory");
    }

    if(res1 && res2){
        res1 = m_bufobj->bindMemory(*m_memory);
    }

    if(!res1){
        SPDLOG_ERROR(__FUNCTION__ " Can not Bind kpext::RawDeviceMemory "
                                  "to kpext::RawBuffer!");
    }else{
        SPDLOG_DEBUG("Bind kpext::RawDeviceMemory to kpext::RawBuffer");
    }

    m_size = size;
}
